package com.illtamer.infinite.morii.util;

import org.springframework.lang.NonNull;
import org.springframework.util.Assert;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public class SecurityUtil {

    private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f'};

    public static String SHA1(File file) {
        try (
                FileInputStream input = new FileInputStream(file)
        ) {
            MessageDigest sha1 = MessageDigest.getInstance("SHA1");
            FileChannel channel = input.getChannel();
            MappedByteBuffer byteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
            sha1.update(byteBuffer);
            byte[] md5 = sha1.digest();
            return getHexMD5(md5);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String SHA1(String string) {
        Assert.notNull(string);
        return SHA1(string.getBytes(StandardCharsets.UTF_8));
    }

    public static String SHA1(byte[] bytes) {
        try {
            MessageDigest sha1 = MessageDigest.getInstance("SHA1");
            final byte[] md5 = sha1.digest(bytes);
            return getHexMD5(md5);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] SHA1Bytes(byte[] bytes) {
        return SHA1(bytes).getBytes(StandardCharsets.UTF_8);
    }

    @NonNull
    public static String MD5(byte[] bytes) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] digest = md5.digest(bytes);
            return new BigInteger(1, digest).toString(16);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    @NonNull
    public static byte[] MD5Bytes(byte[] bytes) {
        return MD5(bytes).getBytes(StandardCharsets.UTF_8);
    }

    private static String getHexMD5(byte[] md5) {
        char[] buffer = new char[md5.length * 2];
        int j = 0;
        for (byte b : md5) {
            buffer[j ++] = HEX_DIGITS[b >>> 4 & 0xf];
            buffer[j ++] = HEX_DIGITS[b & 0xf];
        }
        return new String(buffer);
    }

    public static byte[] ASCBytes(byte[] bytes) {
        return new byte[0];
    }

    public static String ASC(byte[] pom) {
        return "";
    }
}
